<?php
/*
v1.00
bach
2017-01-12
send($demand,$data)
cooldown($demand,$data)
v1.1
2017-07-26
夏浩文
修改channel__sih
*/
namespace app\common\model;
use think\Model;
class Sms extends Model {
    //关闭检测字段
    // protected $autoCheckFields = false;
    private $config;
    private $account;
    private $ip;
    private $isEn;
    function __construct(){
        // $this->$ip = getIp();
        $this->config = getConfig('sms');
        $this->account = config('sms');
    }
    //短信，调用百度API
    private function channel__baidu($demand,$data){
        $need = explode(",",$data['need']);
        foreach ($need as $value) {
            if(!$data['value'][$value]){
                return array('state'=>0,'errormsg'=>"value $value missing",'data'=>$data['value']);
            }
        }
        $templateCode   = $data['template_id'];
        $phoneNumber    = $data['tel'];
        $contentVar     = $data['value'];
        //$content      = $data['content'];
        $config_baidu = C("SMS_BAIDU");
        $profileCode  = $config_baidu['PROFILE_CODE'];
        $apikey       = $config_baidu['API_KEY'];
        // $apikey = '38d5cdf9d5c694e454f6e5f4239a75a2';
        $url = 'http://apis.baidu.com/baidu_communication/baidusms/baidusms?profileCode=' . $profileCode . '&phoneNumber=' . $phoneNumber . '&templateCode=' . $templateCode;
        $contentVar = json_encode($contentVar);  //必须是json串
        $contentVar = urlencode($contentVar);   //必须经过urlencode编码

        $url .= '&contentVar=' . $contentVar;
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_TIMEOUT_MS, 5000);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array("apikey: $apikey"));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $response = curl_exec($ch);
        $response = json_decode($response,1);
        if (curl_errno($ch)) {
            return array('state'=>0,'errormsg'=>'curl error','data'=>array('curl_errno'=>curl_errno($ch)));
            //throw curl_errno($ch);
            //throw new Exception('请求apistore失败!', self::CURL_ERROR);
        }
        curl_close($ch);
        if($response['code'] == '1000'){
            $res = array('state'=>1);
        }else{
            $res = array('state'=>0,'errormsg'=>$response['message'],'data'=>$response);
        }
        return $res;
    }

    private function channel__smscn($demand,$data){
        $config = $this->config[$demand];
        $account = $this->account['account'];
        $pwd = $this->account['secret'];
        $template_id = $this->isEn?$config['template_id_en']:$config['template_id'];
        $tel = $data['tel'];
        $content_array = $data['content'];
        $content = json_encode($content_array);
        $postFields = array(
            'ac'=>'send',
            'uid'=>$account,
            'pwd'=>$pwd,
            'template'=>$template_id,
            'mobile'=>$tel,
            'content'=>$content
            // format => json,
        );
        // $url = "http://api.sms.cn/sms/?ac=number&uid=bachnewton&pwd=117e8a34717470694f994e9d0e2e5508";
        // $url = "http://api.sms.cn/sms/?ac=send&uid=$account&pwd=$pwd&template=$template_id&mobile=$tel&content=$content";
        $url = "http://api.sms.cn/sms/";
        $postFields = http_build_query($postFields);
        // dump($url);
        // dump($postFields);
        // echo $url.'?'.$postFields;
        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_URL, $url );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postFields );
        $result = curl_exec ( $ch );
        curl_close ( $ch );
        // dump($result);
        if( mb_detect_encoding($result,array('ASCII','UTF-8','GB2312','GBK')) != 'UTF-8' ){
            $result = iconv('GBK','UTF-8',$result);
        }
        $result = json_decode($result,true);
        // dump($result);
        if($result['stat'] != "100"){
            $ret = array('state'=>0,'errormsg'=>"sms error ".$result['message'],'errorcode'=>$result['stat']);
            return $ret;
        }
        $ret = array('state'=>1);
        return $ret;

    }
    //sih接口
    private function channel__sih($demand,$data){
        //检查基本数据
        $need = array('content','tel');
        foreach ($need as $value) {
            if(!$data[$value]){
                return array('state'=>0,'errormsg'=>"$value missing");
            }
        }
        $config = $this->config[$demand];
        //放置数据 将value中的内容放入content中
        $value = $data['content'];
        $s = $config['template_text'];
        $i = strpos($s,"{");
        while($i){
            $ii = strpos($s,"}");
            $e = substr($s,$i+2,$ii-$i-2);
            if(!$value[$e]){
                return array('state'=>0,'errormsg'=>"sms value needs $e");
            }
            $s = str_replace('{$'.$e."}",$value[$e],$s);
            $i = strpos($s,"{");
        }
        $content = $s;
        $tel = $data['tel'];
        //开始启用hongyanche肥皂结构发送
        header("content-type:text ml;charset=utf-8");
        $client = new \SoapClient("http://ws.sih.cq.cn/sihwebservice/message/SAPMessageService.asmx?wsdl");
        //$content = "工程师系统测试 hello world";
        $send = array(
            'key'=>"89418D76-0BB7-4311-B8EC-C3B79F6978C0",
            'Message'=>array(
                'Items'=> array(
                    'ReciveMessge'=>array(
                        'Content'=>$content,
                        'PhoneNo'=>$tel
                    ),
                )
            )
        );
        $return = $client->SendMessage($send);
        $return = json_decode(json_encode($return),1);
        $reason = $return['SendMessageResult']['reason'];
        if( strstr($reason,$tel) ){
            $ret = array('state'=>1,'errormsg'=>'sms send success');
        }else{
            $ret = array('state'=>0,'errormsg'=>$reason,'data'=>$return);
        }
        return $ret;
    }
    //选择调用哪一个
    private function channelSelect($demand,$data){
        $channel = isset($this->account['channel'])?$this->account['channel']:null;
        if(!$channel) return array('errormsg'=>'sms_channel config missing');
        $channel = 'channel__'.$channel;
        // if(!$this->$channel) return array(errormsg=>'SMS_CHANNEL config error');
        $res = $this->$channel($demand,$data);
        return $res;
    }
    //冷却时间查询
    public function cooldown($demand,$data){
        $config = $this->config;
        if(!$config){
            return array('state'=>0,'errormsg'=>'config error');
        }
        // dump($config);
        if(!isset($config[$demand])){
            return array('state'=>0,'errormsg'=>'demand error');
        }
        $config = $config[$demand];
        $tel  = $data['tel'];
        if(!$tel){
            return array('state'=>0,'errormsg'=>'tel error');
        }
        $classId  = $config["id"];
        //cool_tel
        $cool = $config['cooldown_tel'];
        if(!$cool){
            return array('state'=>0,'errormsg'=>'cool error');
        }
        $cool     = explode(",",$cool);
        $cooldown = $cool[0];
        $during   = $cool[1];
        $limit    = $cool[2]?$cool[2]:1;
        $order    = "sms_id desc";
        $where  = array(
            "tel"   => $tel,
            "class" => $classId,
        );
        $sendHistory = db('sms')->where($where)->limit($limit)->order($order)->select();
        // dump($res);
        if(count($sendHistory)){
            $lastSendTime = $sendHistory[0]['create_time'];
            $timePassed = time() - $lastSendTime;
            if( $timePassed < $cooldown ){
                $remain = $cooldown - $timePassed;
                return array('state'=>0,'errormsg'=>'sms cooling','data'=>array('remain'=>$remain));
            }
            // dump($lastSendTime);
            // dump($timePassed);
            // die();
            $mostSendTime = isset($sendHistory[$limit-1]['create_time'])?$sendHistory[$limit-1]['create_time']:0;
            if($mostSendTime){
                $timePassed = time() - $mostSendTime;
                if( $timePassed < $during ){
                    $remain = $during - $timePassed;
                    return array('state'=>0,'errormsg'=>'sms send too much','data'=>array('remain'=>$remain));
                }
            }
        }
        $cool = $config['cooldown_ip'];
        if(!$cool){
            return array('state'=>0,'errormsg'=>'ip cool error');
        }
        $cool     = explode(",",$cool);
        $during   = $cool[0];
        $limit    = $cool[1];
        $order    = "sms_id desc";
        $field    = "create_time";
        $where  = array(
            "ip_remote"   => getIp(),
            "class" => $classId,
        );
        $res = db('sms')->where($where)->field($field)->limit($limit-1,1)->order($order)->select();
        $mostSendTime = isset($res[0]['create_time'])?$res[0]['create_time']:null;
        if($mostSendTime){
            $timePassed = time() - $mostSendTime;
            if( $timePassed < $during ){
                $remain = $during - $timePassed;
                return array('state'=>0,'errormsg'=>'this ip send too much','data'=>array('remain'=>$remain));
            }
        }
        return array('state'=>1,'data'=>'sms available');
    }
    public function send($demand, $data) {
        //冷却时间查询
        $cool = $this->coolDown($demand,$data);
        if(!$cool['state']){
            return $cool;
        }
        //内容要求
        $config = $this->config[$demand];
        $para = $config['template_para'];
        foreach (explode(",", $para) as $key => $value) {
            if(!$data[$value]){
                return array('state'=>0,'errormsg'=>"need $value");
            }
            $content[$value] = $data[$value];
        }
        $data['content'] = $content;
        //开始发送

        $res = $this->channelSelect($demand,$data);
        if(!isset($res['state']) || !$res['state']){
            return $res;
        }
        $user = new User;
        $userId = $user->getUserId();
        $tel = $data['tel'];
        $paraSave = $config['template_para_save']?json_encode($content):"";
        $add = array(
            'tel'           => $tel,
            'class'         => $config['id'],
            'create_time'   => time(),
            'ip_remote'     => getIp(),
            'user_id'       => $userId,
            'template_para' => $paraSave,
        );
        db('sms')->insert($add);
        // die();
        $cool = $config['cooldown_tel'];
        $cool_time = explode(",",$cool)[0];
        $a = new Action;
        $a->add('sms',$demand,$tel);
        return array('state'=>1,'errormsg'=>'sms send success','data'=>array('remain'=>$cool_time));
    }
}
